#ifndef KVDB_CONN_SESSION_H_
#define KVDB_CONN_SESSION_H_

#include "vzconn/conn/tcpconnect.h"
#include <set>
#include "glog/logging.h"
#include "sqlite3/sqlite3.h"
#include "kvdb/server/kvdbsqlite.h"
#include "kvdb/base/basedefines.h"

namespace kvdb {

typedef boost::shared_ptr<boost::asio::io_service> io_service_ptr;

class KvdbSession : public boost::noncopyable,
  public boost::enable_shared_from_this < KvdbSession > {
 public:
  typedef boost::shared_ptr<KvdbSession> Ptr;

  // Signal a new tcp connected
  boost::signals2::signal < void(KvdbSession::Ptr kvdb_session,
                                 const boost::system::error_code& err
                                )> SignalSessionError;

  KvdbSession(vzconn::VzConnect::Ptr tcp_connect,
              KvdbSqlite::Ptr kvdb_sqlite);
  virtual ~KvdbSession();

  bool StartSession();
  void StopSession();
 private:
  // With VzConnect callback function
  void OnConnectError(vzconn::VzConnect::Ptr connect,
                      const boost::system::error_code& err);
  void OnConnectWrite(vzconn::VzConnect::Ptr connect);
  void OnConnectRead(vzconn::VzConnect::Ptr connect,
                     const char* buffer, int size, int flag);

  //
  bool ReplaceKeyValue();
  bool DeleteKeyValue();
  bool SelectKeyValue();

  void WriteResponse(const char *data, std::size_t data_size);
  void ResponseSucceed();
  void ResponseFailure();
  //
 private:
  class QueryStanza {
   public:
    QueryStanza();
    virtual ~QueryStanza();
    void ResetStanza() {
      key_.clear();
      value_.clear();
      queury_type_ = KVDB_NONE;
      key_size_ = 0;
      value_size_ = 0;
    }
    bool Parse(const char* buffer, int size);
   private:
    friend class KvdbSession;
    uint8 queury_type_;
    uint8 key_size_;
    uint32 value_size_;
    std::vector<char> key_;
    std::vector<char> value_;
  };
  bool ProcessStanza();
 private:
  boost::asio::io_service& io_service_;
  vzconn::VzConnect::Ptr tcp_connect_;
  KvdbSqlite::Ptr kvdb_sqlite_;
  QueryStanza stanza_;
  std::vector<char> buffer_;
};

}

#endif // KVDB_CONN_SESSION_H_